" Tcl Tool Tooltip/Balloon Plugin
" vim:foldmethod=marker
" File:         tcl_tooltip.vim
" Last Changed: Fri Nov 22 05:02 AM 2013 EST
" Maintainer:   Jessica K McIntosh AT gmail DOT com
" Version:      0.1
" License:      Public Domain
"
" Install:       in ~/.vim/plugin or ~/vimfiles/plugin

" **** XXX This now lives at https://github.com/JessicaKMcIntosh/TagmaTips XXX ****

" Description:
" Displays a tooltip when the cursor hovers over a TCL command or variable.
" When the buffer is written will also scan for all proc definitions.
" A tooltip will thus be displayed for all procedures in the file.
" See :help balloon for details.

" Only process the plugin once. {{{1
if exists("g:loaded_tcl_tooltip") || &cp || !has('balloon_eval')
    finish
endif
let g:loaded_tcl_tooltip = 1

" Function to return the tooltip text. {{{1
function! TclTooltipExpr()
    let l:word = v:beval_text
    let l:descr = []
    if has_key(s:tcl_commands, l:word)
        let l:descr = s:tcl_commands[l:word]
    elseif has_key(b:tcl_procs_local, l:word)
        let l:descr = b:tcl_procs_local[l:word]
    elseif has_key(s:tcl_variables, l:word)
        let l:descr = s:tcl_variables[l:word]
    else
        let l:descr = spellsuggest(spellbadword(v:beval_text)[0], 5, 0 )
    endif
    return join(l:descr, has("balloon_multiline") ? "\n" : " ")
endfunction

" Scan the current buffer for prodecures. {{{1
function! TclTooltipProcScan()
    let b:tcl_procs_local = {}
    let l:eof = line('$')
    let l:lnum = 1
    let l:blank = 0
    " Scan for procedure definitions.
    while l:lnum <= l:eof
        let l:line = getline(l:lnum)
        if match(l:line, '^\s*$') >= 0
            let l:blank = l:lnum
            let l:lnum = l:lnum + 1
            continue
        endif
        let l:matches = matchlist(l:line, '^\s*proc\s\+\(\(::\w\+::\)*\(\S\+\)\s\+.\{-}\)\(\s\+{\s*\)\?$')
        if len(l:matches) != 0
            " Save the procedure.
            let l:proc = l:matches[3]
            let b:tcl_procs_local[l:proc] = []
            call extend(b:tcl_procs_local[l:proc],[l:matches[1], ''])
            " Try to find the description.
            let l:def_lnum = l:blank + 1
            while l:def_lnum < l:lnum && l:def_lnum > l:lnum - 30
                call add(b:tcl_procs_local[l:proc], getline(l:def_lnum))
                let l:def_lnum = l:def_lnum + 1
            endwhile
        endif
        let l:lnum = l:lnum + 1
    endwhile
endfunction

" Setup the balloon options for the current buffer. {{{1
function! TclTooltipsSet()
    " Set the balloonexpr for the buffer if not already set.
    if !exists("b:loaded_tcl_tooltip_buffer")
        let b:loaded_tcl_tooltip_buffer = 1

        " Balloon settings.
        setlocal bexpr=TclTooltipExpr()
        setlocal ballooneval

        " Callback to update the procedure list.
        au BufWritePost * call TclTooltipProcScan()

        " Initialize the local procedure list.
        call TclTooltipProcScan()
    endif
endfunction

" Setup the tooltips and auto command. {{{1
function! TclTooltipsSetup()
    " Check every file to see if it is a Tcl file.
    au BufReadPost,BufNewFile,FileType * if &ft == 'tcl' | call TclTooltipsSet() | endif
endfunction

call TclTooltipsSetup()

" Dictionary of Tcl commands. {{{1
let s:tcl_commands = {
    \ 'after':       ['after - Execute a command after a time delay',
    \                 '',
    \                 'after ms',
    \                 'after ms ?script script script ...?',
    \                 'after cancel id',
    \                 'after cancel script script script ...',
    \                 'after idle ?script script script ...?',
    \                 'after info ?id?'],
    \ 'append':      ['append - Append to variable',
    \                 '',
    \                 'append varName ?value value value ...?'],
    \ 'apply':       ['apply - Apply an anonymous function',
    \                 '',
    \                 'apply func ?arg1 arg2 ...?'],
    \ 'array':       ['array - Manipulate array variables',
    \                 '',
    \                 'array anymore arrayName searchId',
    \                 'array donesearch arrayName searchId',
    \                 'array exists arrayName',
    \                 'array get arrayName ?pattern?',
    \                 'array names arrayName ?mode? ?pattern?',
    \                 'array nextelement arrayName searchId',
    \                 'array set arrayName list',
    \                 'array size arrayName',
    \                 'array startsearch arrayName',
    \                 'array statistics arrayName',
    \                 'array unset arrayName ?pattern?'],
    \ 'auto_execok': ['auto_execok cmd',
    \                 '',
    \                 'Determines whether there is an executable file or shell  builtin by  the  name',
    \                 'cmd.  If so, it returns a list of arguments to be passed to exec to execute the',
    \                 'executable file or  shell  builtin named by cmd.  If not, it returns an empty',
    \                 'string.  This command examines the directories in the current search  path',
    \                 '(given  by the  PATH  environment variable) in its search for an executable',
    \                 'file named cmd.  On Windows platforms, the  search  is  expanded with  the',
    \                 'same directories and file extensions as used by exec.  Auto_execok remembers',
    \                 'information about previous searches in  an array  named  auto_execs;  this',
    \                 'avoids the path search in future calls for the same cmd.  The command',
    \                 'auto_reset may be  used  to force auto_execok to forget its cached information.'],
    \ 'auto_import': ['auto_import pattern',
    \                 '',
    \                 'Auto_import  is  invoked  during  namespace import to see if the imported',
    \                 'commands specified by pattern reside in  an  autoloaded library.  If  so,  the',
    \                 'commands are loaded so that they will be available to the interpreter for',
    \                 'creating the import links.  If the commands do not reside in an autoloaded',
    \                 'library, auto_import does nothing.  The pattern matching is  performed',
    \                 'according  to the matching rules of namespace import.'],
    \ 'auto_load':   ['auto_load cmd',
    \                 '',
    \                 'This  command  attempts to load the definition for a Tcl command named cmd.  To',
    \                 'do this, it searches an auto-load path, which  is a  list of one or more',
    \                 'directories.  The auto-load path is given by the global variable $auto_path if',
    \                 'it exists.  If there is  no $auto_path variable, then the TCLLIBPATH',
    \                 'environment variable is used, if it exists.  Otherwise the auto-load  path',
    \                 'consists  of just  the  Tcl  library directory.  Within each directory in the',
    \                 'auto-load path there must be a file tclIndex that describes  one or more',
    \                 'commands defined in that directory and a script to evaluate to load each of the',
    \                 'commands.  The tclIndex file should  be generated  with the auto_mkindex',
    \                 'command.  If cmd is found in an index file, then the appropriate script is',
    \                 'evaluated  to  create the  command.  The  auto_load command returns 1 if cmd',
    \                 'was successfully created.  The command returns 0 if there was no  index entry',
    \                 'for cmd or if the script did not actually define cmd (e.g.  because index',
    \                 'information is out of date).  If an  error  occurs while  processing  the',
    \                 'script,  then  that  error  is returned.  Auto_load only reads the index',
    \                 'information once and saves it  in the  array  auto_index;  future calls to',
    \                 'auto_load check for cmd in the array rather than re-reading the index files.',
    \                 'The cached index  information  may  be deleted with the command auto_reset.',
    \                 'This will force the next auto_load command to reload  the  index database from',
    \                 'disk.'],
    \ 'auto_mkindex': ['auto_mkindex dir pattern pattern ...',
    \                 '',
    \                 'Generates  an  index suitable for use by auto_load.  The command searches dir',
    \                 'for all files whose names match any of the  pattern arguments (matching is done',
    \                 'with the glob command), generates an index of all the Tcl  command  procedures',
    \                 'defined  in  all  the matching files, and stores the index information in a',
    \                 'file named tclIndex in dir. If no pattern is given a pattern of *.tcl  will be',
    \                 'assumed.  For example, the command auto_mkindex foo *.tcl'],
    \ 'auto_reset':  ['auto_reset',
    \                 '',
    \                 'Destroys   all   the   information  cached  by  auto_execok  and auto_load.',
    \                 'This information will be re-read from disk the  next time  it  is  needed.',
    \                 'Auto_reset  also  deletes any procedures listed in the auto-load index, so that',
    \                 'fresh copies of them will be loaded the next time that they are used.'],
    \ 'auto_qualify': ['auto_qualify command namespace',
    \                 '',
    \                 'Computes a list of fully qualified names for command.  This list mirrors the',
    \                 'path a standard Tcl interpreter follows for  command lookups:   first  it looks',
    \                 'for the command in the current namespace, and then in the global namespace.',
    \                 'Accordingly, if command is  relative  and namespace is not ::, the list',
    \                 'returned has two elements:  command scoped by namespace, as if it were a',
    \                 'command in  the namespace namespace; and command as if it were a command in the',
    \                 'global namespace.  Otherwise, if either command is  absolute  (it begins with',
    \                 '::), or namespace is ::, the list contains only command as if it were a command',
    \                 'in the global namespace.  Auto_qualify is used by the auto-loading facilities',
    \                 'in Tcl, both for producing auto-loading indexes such as pkgIndex.tcl, and for',
    \                 'performing the actual auto-loading of functions at runtime.'],
    \ 'bgerror':     ['bgerror - Command invoked to process background errors',
    \                 '',
    \                 'bgerror message'],
    \ 'binary':      ['binary - Insert and extract fields from binary strings',
    \                 '',
    \                 'binary format formatString ?arg arg ...?',
    \                 'binary scan string formatString ?varName varName ...?'],
    \ 'break':       ['break - Abort looping command',
    \                 '',
    \                 'break'],
    \ 'case':        ['case - Evaluate one of several scripts, depending on a given value',
    \                 '',
    \                 'case string ?in? patList body ?patList body ...?',
    \                 'case string ?in? {patList body ?patList body ...?}'],
    \ 'catch':       ['catch - Evaluate script and trap exceptional returns',
    \                 '',
    \                 'catch script ?resultVarName? ?optionsVarName?'],
    \ 'cd':          ['cd - Change working directory',
    \                 '',
    \                 'cd ?dirName?'],
    \ 'chan':        ['chan - Read, write and manipulate channels',
    \                 '',
    \                 'chan option ?arg arg ...?',
    \                 'chan blocked channelId',
    \                 'chan close channelId',
    \                 'chan configure channelId ?optionName? ?value? ?optionName value?...',
    \                 'chan copy inputChan outputChan ?-size size? ?-command callback?',
    \                 'chan create mode cmdPrefix',
    \                 'chan eof channelId',
    \                 'chan event channelId event ?script?',
    \                 'chan flush channelId',
    \                 'chan gets channelId ?varName?',
    \                 'chan gets channelId ?varName?',
    \                 'chan names ?pattern?',
    \                 'chan pending mode channelId',
    \                 'chan postevent channelId eventSpec',
    \                 'chan puts ?-nonewline? ?channelId? string',
    \                 'chan read channelId ?numChars?',
    \                 'chan read ?-nonewline? channelId',
    \                 'chan seek channelId offset ?origin?',
    \                 'chan tell channelId',
    \                 'chan truncate channelId ?length?'],
    \ 'clock':       ['clock - Obtain and manipulate dates and times',
    \                 '',
    \                 'package require Tcl 8.5',
    \                 'clock add timeVal ?count unit...? ?-option value?',
    \                 'clock clicks ?-option?',
    \                 'clock format timeVal ?-option value...?',
    \                 'clock microseconds',
    \                 'clock milliseconds',
    \                 'clock scan inputString ?-option value...?',
    \                 'clock seconds'],
    \ 'close':       ['close - Close an open channel',
    \                 '',
    \                 'close channelId'],
    \ 'concat':      ['concat - Join lists together',
    \                 '',
    \                 'concat ?arg arg ...?'],
    \ 'continue':    ['continue - Skip to the next iteration of a loop',
    \                 '',
    \                 'continue'],
    \ 'dde':         ['dde - Execute a Dynamic Data Exchange command',
    \                 '',
    \                 'package require dde 1.3',
    \                 'dde servername ?-force? ?-handler proc? ?--? ?topic?',
    \                 'dde execute ?-async? service topic data',
    \                 'dde poke service topic item data',
    \                 'dde request ?-binary? service topic item',
    \                 'dde services service topic',
    \                 'dde eval ?-async? topic cmd ?arg arg ...?'],
    \ 'dict':        ['dict - Manipulate dictionaries',
    \                 '',
    \                 'dict append dictionaryVariable key ?string ...?',
    \                 'dict create ?key value ...?',
    \                 'dict exists dictionaryValue key ?key ...?',
    \                 'dict filter dictionaryValue filterType arg ?arg ...?',
    \                 'dict for {keyVar valueVar} dictionaryValue body',
    \                 'dict get dictionaryValue ?key ...?',
    \                 'dict incr dictionaryVariable key ?increment?',
    \                 'dict info dictionaryValue',
    \                 'dict keys dictionaryValue ?globPattern?',
    \                 'dict lappend dictionaryVariable key ?value ...?',
    \                 'dict merge ?dictionaryValue ...?',
    \                 'dict remove dictionaryValue ?key ...?',
    \                 'dict replace dictionaryValue ?key value ...?',
    \                 'dict set dictionaryVariable key ?key ...? value',
    \                 'dict size dictionaryValue',
    \                 'dict unset dictionaryVariable key ?key ...?',
    \                 'dict update dictionaryVariable key varName ?key varName ...? body',
    \                 'dict values dictionaryValue ?globPattern?',
    \                 'dict with dictionaryVariable ?key ...? body'],
    \ 'encoding':    ['encoding - Manipulate encodings',
    \                 '',
    \                 'encoding convertfrom ?encoding? data',
    \                 'encoding convertto ?encoding? string',
    \                 'encoding dirs ?directoryList?',
    \                 'encoding names',
    \                 'encoding system ?encoding?'],
    \ 'eof':         ['eof - Check for end of file condition on channel',
    \                 '',
    \                 'eof channelId'],
    \ 'error':       ['error - Generate an error',
    \                 '',
    \                 'error message ?info? ?code?'],
    \ 'eval':        ['eval - Evaluate a Tcl script',
    \                 '',
    \                 'eval arg ?arg ...?'],
    \ 'exec':        ['exec - Invoke subprocesses',
    \                 '',
    \                 'exec ?switches? arg ?arg ...?'],
    \ 'exit':        ['exit - End the application',
    \                 '',
    \                 'exit ?returnCode?'],
    \ 'expr':        ['expr - Evaluate an expression',
    \                 '',
    \                 'expr arg ?arg arg ...?'],
    \ 'fblocked':    ['fblocked  -  Test whether the last input operation exhausted all available input',
    \                 '',
    \                 'fblocked channelId'],
    \ 'fconfigure':  ['fconfigure - Set and get options on a channel',
    \                 '',
    \                 'fconfigure channelId',
    \                 'fconfigure channelId name',
    \                 'fconfigure channelId name value ?name value ...?'],
    \ 'fcopy':       ['fcopy - Copy data from one channel to another',
    \                 '',
    \                 'fcopy inchan outchan ?-size size? ?-command callback?'],
    \ 'file':        ['file - Manipulate file names and attributes',
    \                 '',
    \                 'file atime name ?time?',
    \                 'file attributes name ?option value option value...?',
    \                 'file channels ?pattern?',
    \                 'file copy ?-force? ?--? source target',
    \                 'file copy ?-force? ?--? source ?source ...? targetDir',
    \                 'file delete ?-force? ?--? pathname ?pathname ... ?',
    \                 'file dirname name',
    \                 'file executable name',
    \                 'file exists name',
    \                 'file extension name',
    \                 'file isdirectory name',
    \                 'file isfile name',
    \                 'file join name ?name ...?',
    \                 'file link ?-linktype? linkName ?target?',
    \                 'file lstat name varName',
    \                 'file mkdir dir ?dir ...?',
    \                 'file mtime name ?time?',
    \                 'file nativename name',
    \                 'file normalize name',
    \                 'file owned name',
    \                 'file pathtype name',
    \                 'file readable name',
    \                 'file readlink name',
    \                 'file rename ?-force? ?--? source target',
    \                 'file rename ?-force? ?--? source ?source ...? targetDir',
    \                 'file rootname name',
    \                 'file separator ?name?',
    \                 'file size name',
    \                 'file split name',
    \                 'file stat  name varName',
    \                 'file system name',
    \                 'file tail name',
    \                 'file type name',
    \                 'file volumes',
    \                 'file writable name'],
    \ 'fileevent':   ['fileevent  -  Execute  a  script  when  a  channel  becomes readable or writable',
    \                 '',
    \                 'fileevent channelId readable ?script?',
    \                 'fileevent channelId writable ?script?'],
    \ 'filename':    ['filename - File name conventions supported by Tcl commands'],
    \ 'flush':       ['flush - Flush buffered output for a channel',
    \                 '',
    \                 'flush channelId'],
    \ 'for':         ['for - "For" loop',
    \                 '',
    \                 'for start test next body'],
    \ 'foreach':     ['foreach - Iterate over all elements in one or more lists',
    \                 '',
    \                 'foreach varname list body',
    \                 'foreach varlist1 list1 ?varlist2 list2 ...? body'],
    \ 'format':      ['format - Format a string in the style of sprintf',
    \                 '',
    \                 'format formatString ?arg arg ...?'],
    \ 'gets':        ['gets - Read a line from a channel',
    \                 '',
    \                 'gets channelId ?varName?'],
    \ 'glob':        ['glob - Return names of files that match patterns',
    \                 '',
    \                 'glob ?switches? pattern ?pattern ...?'],
    \ 'global':      ['global - Access global variables',
    \                 '',
    \                 'global varname ?varname ...?'],
    \ 'history':     ['history - Manipulate the history list',
    \                 '',
    \                 'history ?option? ?arg arg ...?',
    \                 'history add command ?exec?',
    \                 'history change newValue ?event?',
    \                 'history clear',
    \                 'history event ?event?',
    \                 'history info ?count?',
    \                 'history keep ?count?',
    \                 'history nextid',
    \                 'history redo ?event?'],
    \ 'if':          ['if - Execute scripts conditionally',
    \                 '',
    \                 'if  expr1  ?then?  body1  elseif  expr2  ?then? body2 elseif ... ?else? ?bodyN?'],
    \ 'incr':        ['incr - Increment the value of a variable',
    \                 '',
    \                 'incr varName ?increment?'],
    \ 'info':        ['info - Return information about the state of the Tcl interpreter',
    \                 '',
    \                 'info args procname',
    \                 'info body procname',
    \                 'info cmdcount',
    \                 'info commands ?pattern?',
    \                 'info complete command',
    \                 'info default procname arg varname',
    \                 'info exists varName',
    \                 'info frame ?number?',
    \                 'info functions ?pattern?',
    \                 'info globals ?pattern?',
    \                 'info hostname',
    \                 'info level ?number?',
    \                 'info library',
    \                 'info loaded ?interp?',
    \                 'info locals ?pattern?',
    \                 'info nameofexecutable',
    \                 'info patchlevel',
    \                 'info procs ?pattern?',
    \                 'info script ?filename?',
    \                 'info sharedlibextension',
    \                 'info tclversion',
    \                 'info vars ?pattern?'],
    \ 'interp':      ['interp - Create and manipulate Tcl interpreters',
    \                 '',
    \                 'interp alias srcPath srcToken',
    \                 'interp alias srcPath srcToken {}',
    \                 'interp alias srcPath srcCmd targetPath targetCmd ?arg arg ...?',
    \                 'interp aliases ?path?',
    \                 'interp bgerror path ?cmdPrefix?',
    \                 'interp create ?-safe? ?--? ?path?',
    \                 'interp delete ?path ...?',
    \                 'interp eval path arg ?arg ...?',
    \                 'interp exists path',
    \                 'interp expose path hiddenName ?exposedCmdName?',
    \                 'interp hide path exposedCmdName ?hiddenCmdName?',
    \                 'interp hidden path',
    \                 'interp invokehidden path ?-option ...? hiddenCmdName ?arg ...?',
    \                 'interp limit path limitType ?-option? ?value ...?',
    \                 'interp issafe ?path?',
    \                 'interp marktrusted path',
    \                 'interp recursionlimit path ?newlimit?',
    \                 'interp share srcPath channelId destPath',
    \                 'interp slaves ?path?',
    \                 'interp target path alias',
    \                 'interp transfer srcPath channelId destPath'],
    \ 'join':        ['join - Create a string by joining together list elements',
    \                 '',
    \                 'join list ?joinString?'],
    \ 'lappend':     ['lappend - Append list elements onto a variable',
    \                 '',
    \                 'lappend varName ?value value value ...?'],
    \ 'lassign':     ['lassign - Assign list elements to variables',
    \                 '',
    \                 'lassign list varName ?varName ...?'],
    \ 'lindex':      ['lindex - Retrieve an element from a list',
    \                 '',
    \                 'lindex list ?index...?'],
    \ 'linsert':     ['linsert - Insert elements into a list',
    \                 '',
    \                 'linsert list index element ?element element ...?'],
    \ 'list':        ['list - Create a list',
    \                 '',
    \                 'list ?arg arg ...?'],
    \ 'llength':     ['llength - Count the number of elements in a list',
    \                 '',
    \                 'llength list'],
    \ 'load':        ['load - Load machine code and initialize new commands',
    \                 '',
    \                 'load fileName',
    \                 'load fileName packageName',
    \                 'load fileName packageName interp'],
    \ 'lrange':      ['lrange - Return one or more adjacent elements from a list',
    \                 '',
    \                 'lrange list first last'],
    \ 'lrepeat':     ['lrepeat - Build a list by repeating elements',
    \                 '',
    \                 'lrepeat number element1 ?element2 element3 ...?'],
    \ 'lreplace':    ['lreplace - Replace elements in a list with new elements',
    \                 '',
    \                 'lreplace list first last ?element element ...?'],
    \ 'lreverse':    ['lreverse - Reverse the order of a list',
    \                 '',
    \                 'lreverse list'],
    \ 'lsearch':     ['lsearch - See if a list contains a particular element',
    \                 '',
    \                 'lsearch ?options? list pattern'],
    \ 'lset':        ['lset - Change an element in a list',
    \                 '',
    \                 'lset varName ?index...? newValue'],
    \ 'lsort':       ['lsort - Sort the elements of a list',
    \                 '',
    \                 'lsort ?options? list'],
    \ 'memory':      ['memory - Control Tcl memory debugging capabilities',
    \                 '',
    \                 'memory active file',
    \                 'memory break_on_malloc count',
    \                 'memory info',
    \                 'memory init [on|off]',
    \                 'memory objs file',
    \                 'memory onexit file',
    \                 'memory tag string',
    \                 'memory trace [on|off]',
    \                 'memory trace_on_at_malloc count',
    \                 'memory validate [on|off]'],
    \ 'namespace':   ['namespace - create and manipulate contexts for commands and variables',
    \                 '',
    \                 'namespace children ?namespace? ?pattern?',
    \                 'namespace code script',
    \                 'namespace current',
    \                 'namespace delete ?namespace namespace ...?',
    \                 'namespace ensemble subcommand ?arg ...?',
    \                 'namespace eval namespace arg ?arg ...?',
    \                 'namespace exists namespace',
    \                 'namespace export ?-clear? ?pattern pattern ...?',
    \                 'namespace forget ?pattern pattern ...?',
    \                 'namespace import ?-force? ?pattern pattern ...?',
    \                 'namespace inscope namespace script ?arg ...?',
    \                 'namespace origin command',
    \                 'namespace parent ?namespace?',
    \                 'namespace path ?namespaceList?',
    \                 'namespace qualifiers string',
    \                 'namespace tail string',
    \                 'namespace upvar namespace otherVar myVar ?otherVar myVar ...',
    \                 'namespace unknown ?script?',
    \                 'namespace which ?-command? ?-variable? name'],
    \ 'open':        ['open - Open a file-based or command pipeline channel',
    \                 '',
    \                 'open fileName',
    \                 'open fileName access',
    \                 'open fileName access permissions'],
    \ 'package':     ['package - Facilities for package loading and version control',
    \                 '',
    \                 'package forget ?package package ...?',
    \                 'package ifneeded package version ?script?',
    \                 'package names',
    \                 'package present package ?requirement...?',
    \                 'package present -exact package version',
    \                 'package provide package ?version?',
    \                 'package require package ?requirement...?',
    \                 'package require -exact package version',
    \                 'package unknown ?command?',
    \                 'package vcompare version1 version2',
    \                 'package versions package',
    \                 'package vsatisfies version requirement...',
    \                 'package prefer ?latest|stable?'],
    \ 'parray':      ['parray arrayName',
    \                 '',
    \                 'Prints  on  standard output the names and values of all the elements in the',
    \                 'array arrayName.  ArrayName must be an array accessible  to  the  caller  of',
    \                 'parray.  It  may be either local or global.'],
    \ 'pid':         ['pid - Retrieve process identifiers',
    \                 '',
    \                 'pid ?fileId?'],
    \ 'pkg_mkIndex': ['pkg_mkIndex - Build an index for automatic loading of packages',
    \                 '',
    \                 'pkg_mkIndex ?-direct?  ?-lazy?  ?-load pkgPat? ?-verbose? dir ?pattern pattern ...?'],
    \ 'proc':        ['proc - Create a Tcl procedure',
    \                 '',
    \                 'proc name args body'],
    \ 'puts':        ['puts - Write to a channel',
    \                 '',
    \                 'puts ?-nonewline? ?channelId? string'],
    \ 'pwd':         ['pwd - Return the absolute path of the current working directory',
    \                 '',
    \                 'pwd'],
    \ 'read':        ['read - Read from a channel',
    \                 '',
    \                 'read ?-nonewline? channelId',
    \                 'read channelId numChars'],
    \ 'refchan':     ['refchan - Command handler API of reflected channels, version 1',
    \                 '',
    \                 'cmdPrefix option ?arg arg ...?'],
    \ 'regexp':      ['regexp - Match a regular expression against a string',
    \                 '',
    \                 'regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?'],
    \ 'registry':    ['registry - Manipulate the Windows registry',
    \                 '',
    \                 'package require registry 1.1',
    \                 'registry option keyName ?arg arg ...?',
    \                 'registry broadcast keyName ?-timeout milliseconds?',
    \                 'registry delete keyName ?valueName?',
    \                 'registry get keyName valueName',
    \                 'registry keys keyName ?pattern?',
    \                 'registry set keyName ?valueName data ?type??',
    \                 'registry type keyName valueName',
    \                 'registry values keyName ?pattern?'],
    \ 'regsub':      ['regsub  -  Perform  substitutions  based  on regular expression pattern matching',
    \                 '',
    \                 'regsub ?switches? exp string subSpec ?varName?'],
    \ 'rename':      ['rename - Rename or delete a command',
    \                 '',
    \                 'rename oldName newName'],
    \ 'return':      ['return - Return from a procedure, or set return code of a script',
    \                 '',
    \                 'return ?result?',
    \                 'return ?-code code? ?result?',
    \                 'return ?option value ...? ?result?'],
    \ 'scan':        ['scan - Parse string using conversion specifiers in the style of sscanf',
    \                 '',
    \                 'scan string format ?varName varName ...?'],
    \ 'seek':        ['seek - Change the access position for an open channel',
    \                 '',
    \                 'seek channelId offset ?origin?'],
    \ 'set':         ['set - Read and write variables',
    \                 '',
    \                 'set varName ?value?'],
    \ 'socket':      ['socket - Open a TCP network connection',
    \                 '',
    \                 'socket ?options? host port',
    \                 'socket -server command ?options? port'],
    \ 'source':      ['source - Evaluate a file or resource as a Tcl script',
    \                 '',
    \                 'source fileName',
    \                 'source -encoding encodingName fileName'],
    \ 'split':       ['split - Split a string into a proper Tcl list',
    \                 '',
    \                 'split string ?splitChars?'],
    \ 'string':      ['string - Manipulate strings',
    \                 '',
    \                 'string option arg ?arg ...?'],
    \ 'subst':       ['subst - Perform backslash, command, and variable substitutions',
    \                 '',
    \                 'subst ?-nobackslashes? ?-nocommands? ?-novariables? string'],
    \ 'switch':      ['switch - Evaluate one of several scripts, depending on a given value',
    \                 '',
    \                 'switch ?options? string pattern body ?pattern body ...?',
    \                 'switch ?options? string {pattern body ?pattern body ...?}'],
    \ 'tcl_findLibrary': ['tcl_findLibrary basename version patch initScript enVarName varName',
    \                 '',
    \                 'This is a standard search procedure for use by extensions during their',
    \                 'initialization.  They  call  this  procedure to look for their script library',
    \                 'in several standard directories.  The  last component of the name of the',
    \                 'library directory is normally basenameversion (e.g., tk8.0), but it might be',
    \                 "'library' when in the build hierarchies.  The initScript file will be sourced",
    \                 'into the interpreter once it is found.  The directory in which this  file is',
    \                 'found  is  stored into the global variable varName.  If this variable is',
    \                 'already defined (e.g., by C code during  application initialization) then no',
    \                 'searching is done.  Otherwise the search looks in these directories: the',
    \                 'directory named by the  environment  variable enVarName; relative to the Tcl',
    \                 'library directory; relative to the executable file in the standard installation',
    \                 'bin or  bin/arch  directory;  relative to the executable file in the current',
    \                 'build tree; relative to the executable file in a  parallel build tree.'],
    \ 'tcl_endOfWord': ['tcl_endOfWord str start',
    \                 '',
    \                 'Returns the index of the first end-of-word location that  occurs after  a',
    \                 'starting index start in the string str.  An end-of-word location is defined to',
    \                 'be the first non-word character following the  first  word character after the',
    \                 'starting point.  Returns -1 if there are no more end-of-word locations  after',
    \                 'the  starting point.  See  the  description of tcl_wordchars and',
    \                 'tcl_nonwordchars below for more details on how Tcl determines which characters',
    \                 'are word characters.'],
    \ 'tcl_startOfNextWord': ['tcl_startOfNextWord str start',
    \                 '',
    \                 'Returns  the  index  of  the  first  start-of-word location that occurs after a',
    \                 'starting index start in the string str.  A startof-word  location is defined to',
    \                 'be the first word character following a non-word character.  Returns -1 if',
    \                 'there  are  no  more start-of-word locations after the starting point.'],
    \ 'tcl_startOfPreviousWord': ['tcl_startOfPreviousWord str start',
    \                 '',
    \                 'Returns  the  index  of  the  first  start-of-word location that occurs before',
    \                 'a starting index start in the string str.  Returns -1  if  there  are  no  more',
    \                 'start-of-word locations before the starting point.'],
    \ 'tcl_wordBreakAfter': ['tcl_wordBreakAfter str start',
    \                 '',
    \                 'Returns the index of the first word boundary after the  starting index  start',
    \                 'in the string str.  Returns -1 if there are no more boundaries after the',
    \                 'starting point in the  given  string.  The index  returned  refers to the',
    \                 'second character of the pair that comprises a boundary.'],
    \ 'tcl_wordBreakBefore': ['tcl_wordBreakBefore str start',
    \                 '',
    \                 'Returns the index of the first word boundary before the starting index  start',
    \                 'in the string str.  Returns -1 if there are no more boundaries before the',
    \                 'starting point in the given  string.  The index  returned  refers to the',
    \                 'second character of the pair that comprises a boundary.'],
    \ 'tell':        ['tell - Return current access position for an open channel',
    \                 '',
    \                 'tell channelId'],
    \ 'time':        ['time - Time the execution of a script',
    \                 '',
    \                 'time script ?count?'],
    \ 'trace':       ['trace  -  Monitor  variable accesses, command usages and command executions',
    \                 '',
    \                 'trace add command name ops commandPrefix',
    \                 'trace add execution name ops commandPrefix',
    \                 'trace add variable name ops commandPrefix',
    \                 'trace remove command name opList commandPrefix',
    \                 'trace remove execution name opList commandPrefix',
    \                 'trace remove variable name opList commandPrefix',
    \                 'trace info command name',
    \                 'trace info execution name',
    \                 'trace info variable name',
    \                 'trace variable name ops command',
    \                 'trace vdelete name ops command',
    \                 'trace vinfo name'],
    \ 'unknown':     ['unknown - Handle attempts to use non-existent commands',
    \                 '',
    \                 'unknown cmdName ?arg arg ...?'],
    \ 'unload':      ['unload - Unload machine code',
    \                 '',
    \                 'unload ?switches? fileName',
    \                 'unload ?switches? fileName packageName',
    \                 'unload ?switches? fileName packageName interp'],
    \ 'unset':       ['unset - Delete variables',
    \                 '',
    \                 'unset ?-nocomplain? ?--? ?name name name ...?'],
    \ 'update':      ['update - Process pending events and idle callbacks',
    \                 '',
    \                 'update ?idletasks?'],
    \ 'uplevel':     ['uplevel - Execute a script in a different stack frame',
    \                 '',
    \                 'uplevel ?level? arg ?arg ...?'],
    \ 'upvar':       ['upvar - Create link to variable in a different stack frame',
    \                 '',
    \                 'upvar ?level? otherVar myVar ?otherVar myVar ...?'],
    \ 'variable':    ['variable - create and initialize a namespace variable',
    \                 '',
    \                 'variable ?name value...? name ?value?'],
    \ 'vwait':       ['vwait - Process events until a variable is written',
    \                 '',
    \                 'vwait varName'],
    \ 'while':       ['while - Execute script repeatedly as long as a condition is met',
    \                 '',
    \                 'while test body'],
    \ }

" Dictionary of Tcl variables. {{{1
let s:tcl_variables = {
    \ 'TCLLIBPATH':  ["env(TCLLIBPATH)",
    \                 '',
    \                 "If set, then it must contain a valid Tcl list giving directories to  search",
    \                 "during  auto-load  operations.  Directories must be specified in Tcl format,",
    \                 "using  '/'  as  the  path  separator, regardless  of  platform.  This variable",
    \                 "is only used when initializing the auto_path variable."],
    \ 'TCL_LIBRARY': ["env(TCL_LIBRARY)",
    \                 '',
    \                 "If set, then it specifies the location of the directory containing library",
    \                 "scripts (the value of this variable will be assigned to the tcl_library",
    \                 "variable and therefore returned by  the  command  info library).  If this",
    \                 "variable is not set then a default value is used."],
    \ 'argc':        ["argc",
    \                 '',
    \                 "The number of arguments to tclsh or wish."],
    \ 'argv':        ["argv",
    \                 '',
    \                 "Tcl list of arguments to tclsh or wish."],
    \ 'argv0':       ["argv0",
    \                 '',
    \                 "The script that tclsh or wish started executing (if it was specified) or",
    \                 "otherwise the name by which tclsh or wish was invoked."],
    \ 'auto_execs':  ["auto_execs",
    \                 '',
    \                 "Used by auto_execok to record information about whether particular commands",
    \                 "exist as executable files."],
    \ 'auto_index':  ["auto_index",
    \                 '',
    \                 "Used by auto_load to save the index information read from disk."],
    \ 'auto_noexec': ["auto_noexec",
    \                 '',
    \                 "If set to any value, then unknown will not attempt to  auto-exec any",
    \                 "commands."],
    \ 'auto_noload': ["auto_noload",
    \                 '',
    \                 "If  set to any value, then unknown will not attempt to auto-load any",
    \                 "commands."],
    \ 'auto_path':   ["auto_path",
    \                 '',
    \                 "If set, then it must contain a valid Tcl list giving directories to  search",
    \                 "during  auto-load operations.  This variable is initialized during startup to",
    \                 "contain, in  order:  the  directories listed  in  the  TCLLIBPATH environment",
    \                 "variable, the directory named by the $tcl_library  variable,  the parent",
    \                 "directory  of $tcl_library,  the  directories listed in the $tcl_pkgPath",
    \                 "variable."],
    \ 'env':         ["env",
    \                 '',
    \                 "This variable is maintained by Tcl as an  array  whose  elements are  the",
    \                 "environment variables for the process.  Reading an element will return the",
    \                 "value  of  the  corresponding  environment variable.  Setting an element of",
    \                 "the array will modify the corresponding environment variable or create a new",
    \                 "one if  it  does not  already exist.  Unsetting an element of env will remove",
    \                 "the corresponding environment variable.  Changes to  the  env  array will",
    \                 "affect the environment passed to children by commands like exec.  If the",
    \                 "entire env array is unset then Tcl will stop monitoring env accesses and will",
    \                 "not update environment variables."],
    \ 'errorCode':   ["errorCode",
    \                 '',
    \                 "This  variable  holds  the value of the -errorcode return option set by the",
    \                 "most recent error that occurred in this  interpreter.  This  list  value",
    \                 "represents  additional  information about the error in a form that is easy  to",
    \                 "process  with  programs.  The first  element of the list identifies a general",
    \                 "class of errors, and determines the format of the rest of the list.  The",
    \                 "following  formats  for  -errorcode return options are used by the Tcl core;",
    \                 "individual applications may define additional formats."],
    \ 'errorInfo':   ["errorInfo",
    \                 '',
    \                 "This  variable  holds  the value of the -errorinfo return option set by the",
    \                 "most recent error that occurred in this  interpreter.  This string value will",
    \                 "contain one or more lines identifying the Tcl commands and procedures that",
    \                 "were being  executed  when  the most  recent  error  occurred.  Its contents",
    \                 "take the form of a stack trace showing the various nested  Tcl  commands  that",
    \                 "had been invoked at the time of the error."],
    \ 'tcl_interactive': ["tcl_interactive",
    \                 '',
    \                 "Contains  1  if tclsh or wish is running interactively (no script was",
    \                 "specified and standard input is a  terminal-like  device),  0 otherwise."],
    \ 'tcl_library': ["tcl_library",
    \                 '',
    \                 "This  variable holds the name of a directory containing the system library of",
    \                 "Tcl scripts, such as those used for auto-loading.  The  value of this variable",
    \                 "is returned by the info library command.  See the library manual entry for",
    \                 "details of  the  facilities provided by the Tcl script library.  Normally each",
    \                 "application or package will have its  own  application-specific  script",
    \                 "library  in addition to the Tcl script library; each application should set a",
    \                 "global  variable  with  a  name  like  $app_library (where  app  is the",
    \                 "application's name) to hold the network file name for that  application's",
    \                 "library  directory.  The  initial value  of  tcl_library  is set when an",
    \                 "interpreter is created by searching several different directories until one is",
    \                 "found  that contains  an appropriate Tcl startup script.  If the TCL_LIBRARY",
    \                 "environment variable exists, then  the  directory  it  names  is checked",
    \                 "first.  If TCL_LIBRARY is not set or doesn't refer to an appropriate",
    \                 "directory, then Tcl checks several other directories based  on  a  compiled-in",
    \                 "default location, the location of the binary containing  the  application,",
    \                 "and  the  current  working directory."],
    \ 'tcl_nonwordchars': ["tcl_nonwordchars",
    \                 '',
    \                 "The  value  of this variable is a regular expression that can be set to",
    \                 "control what are considered  'non-word'  characters,  for instances  like",
    \                 "selecting  a word by double-clicking in text in Tk.  It is platform dependent.",
    \                 "On Windows, it defaults  to  \s, meaning  any  Unicode space character.",
    \                 "Otherwise it defaults to \W, which is anything but a Unicode word character",
    \                 "(number, letter, or underscore)."],
    \ 'tcl_patchLevel': ["tcl_patchLevel",
    \                 '',
    \                 "When  an interpreter is created Tcl initializes this variable to hold a string",
    \                 "giving the current patch level for  Tcl,  such  as 8.4.16  for  Tcl 8.4 with",
    \                 "the first sixteen official patches, or 8.5b3 for the third beta release of Tcl",
    \                 " 8.5.  The value of  this variable is returned by the info patchlevel",
    \                 "command."],
    \ 'tcl_pkgPath': ["tcl_pkgPath",
    \                 '',
    \                 "This variable holds a list of directories indicating where packages are",
    \                 "normally installed.  It is not  used  on  Windows.  It typically contains",
    \                 "either one or two entries; if it contains two entries, the first is normally a",
    \                 "directory  for  platform-dependent  packages (e.g., shared library binaries)",
    \                 "and the second is normally a directory for  platform-independent  packages",
    \                 "(e.g., script  files).  Typically a package is installed as a subdirectory of",
    \                 "one of the entries in $tcl_pkgPath. The  directories  in $tcl_pkgPath  are",
    \                 "included by default in the auto_path variable, so they and their  immediate",
    \                 "subdirectories  are  automatically searched  for  packages  during package",
    \                 "require commands.  Note: tcl_pkgPath is not intended to be modified by  the",
    \                 "application.  Its  value is added to auto_path at startup; changes to",
    \                 "tcl_pkgPath are not reflected in auto_path.  If you want Tcl to  search",
    \                 "additional  directories for packages you should add the names of those",
    \                 "directories to auto_path, not tcl_pkgPath."],
    \ 'tcl_platform': ["tcl_platform",
    \                 '',
    \                 "This is an associative array whose elements contain  information about  the",
    \                 "platform on which the application is running, such as the name of the",
    \                 "operating system, its  current  release  number, and  the  machine's",
    \                 "instruction set.  The elements listed below will always be defined, but they",
    \                 "may have empty strings as  values  if  Tcl  could  not  retrieve any relevant",
    \                 "information.  In addition, extensions and applications may add additional",
    \                 "values to the array."],
    \ 'tcl_precision': ["tcl_precision",
    \                 '',
    \                 "This  variable  controls  the  number of digits to generate when converting",
    \                 "floating-point values to strings.  It defaults to  0.  Applications  should",
    \                 "not  change this value; it is provided for compatibility with legacy code."],
    \ 'tcl_rcFileName': ["tcl_rcFileName",
    \                 '',
    \                 "This variable is used during initialization to indicate the name of  a",
    \                 "user-specific startup file.  If it is set by applicationspecific",
    \                 "initialization, then the Tcl startup  code  will  check for  the existence of",
    \                 "this file and source it if it exists.  For example, for wish the variable is",
    \                 "set to ~/.wishrc for Unix  and ~/wishrc.tcl for Windows.",],
    \ 'tcl_traceCompile': ["tcl_traceCompile",
    \                 '',
    \                 "The  value of this variable can be set to control how much tracing information",
    \                 "is displayed during  bytecode  compilation.  By default,  tcl_traceCompile  is",
    \                 "zero  and no information is displayed.  Setting tcl_traceCompile to 1",
    \                 "generates a one-line summary in stdout whenever a procedure or top-level",
    \                 "command is compiled.  Setting it to 2 generates a detailed listing  in  stdout",
    \                 "of  the  bytecode instructions emitted during every compilation.  his variable",
    \                 "is useful in tracking down suspected problems with the Tcl compiler.  This",
    \                 "variable and functionality only exist if TCL_COMPILE_DEBUG was defined during",
    \                 "Tcl's compilation."],
    \ 'tcl_traceExec': ["tcl_traceExec",
    \                 '',
    \                 "The value of this variable can be set to control how much  tracing",
    \                 "information  is  displayed  during  bytecode execution.  By default,",
    \                 "tcl_traceExec is zero and no information is  displayed.  Setting",
    \                 "tcl_traceExec to 1 generates a one-line trace in stdout on each call to a Tcl",
    \                 "procedure.  Setting it to  2  generates  a line of output whenever any Tcl",
    \                 "command is invoked that contains the name of the command and its arguments.",
    \                 "Setting it to 3 produces  a  detailed  trace  showing  the result of executing",
    \                 "each bytecode instruction.  Note that when tcl_traceExec is 2  or  3, commands",
    \                 "such  as set and incr that have been entirely replaced by a sequence of",
    \                 "bytecode instructions are not  shown.  Setting this variable is useful in",
    \                 "tracking down suspected problems with the bytecode compiler and interpreter.",
    \                 "This variable and functionality only exist if  TCL_COMPILE_DEBUG was defined",
    \                 "during Tcl's compilation."],
    \ 'tcl_version': ["tcl_version",
    \                 '',
    \                 "When  an interpreter is created Tcl initializes this variable to hold the",
    \                 "version number for this version of Tcl in the form x.y.  Changes to x",
    \                 "represent major changes with probable incompatibilities and changes to y",
    \                 "represent  small  enhancements  and  bug fixes  that  retain  backward",
    \                 "compatibility.  The value of this variable is returned by the info tclversion",
    \                 "command."],
    \ 'tcl_wordchars': ["tcl_wordchars",
    \                 '',
    \                 "The  value  of this variable is a regular expression that can be set to",
    \                 "control  what  are  considered  'word'  characters,  for instances  like",
    \                 "selecting  a word by double-clicking in text in Tk.  It is platform dependent.",
    \                 "On Windows, it defaults  to  \S, meaning  anything  but  a Unicode space",
    \                 "character.  Otherwise it defaults to \w, which is any  Unicode  word",
    \                 "character  (number, letter, or underscore)."],
    \ }
